package com.zhoug.demo.audiorecorder;

import android.content.Context;

import androidx.annotation.NonNull;

import com.zhoug.audiorecorder.WavHeadUtil;
import com.zhoug.common.utils.LogUtils;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @description: 类的简要描述
 * @author: 35574
 * @date: 2025/10/27 15:57
 */
public class SplitSaveWAVFile implements ISaveWAVFile {
    private static final String TAG = ">>>SaveWAV";
    private Context context;
    private Listener listener;

    private DataOutputStream mDataOutputStream;
    private long mCurrentRecordingStartTime;//当前文件录音开始时间
    private String mRecordingPath;
    private long totalAudioLen;
    private int sampleRate = 16000;

    /**
     * 是否分片保存录音文件
     */
    private boolean splitFile = true;
    /**
     * 分片时长 单位毫秒
     */
    private int splitTime = 60_000;


    public SplitSaveWAVFile(Context context) {
        this.context = context;
    }

    @Override
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    public void setSampleRate(int sampleRate) {
        this.sampleRate = sampleRate;
    }

    /**
     * 是否分片保存录音文件
     * @param splitFile
     */
    public void setSplitFile(boolean splitFile) {
        this.splitFile = splitFile;
    }

    /**
     * 分片时长
     * @param splitTime
     */
    public void setSplitTime(int splitTime) {
        this.splitTime = splitTime;
    }


    public void onAudioDataAvailable(@NonNull byte[] bytes) {
        try {
            if (mDataOutputStream == null || mCurrentRecordingStartTime == 0 || (
                    splitTime < System.currentTimeMillis() - mCurrentRecordingStartTime && splitFile)) {
                if (mDataOutputStream != null && splitFile) {
                    //结束上一个文件
                    stopWriteFile();
                    mRecordingPath = null;
                    mCurrentRecordingStartTime = 0;
                }
                // 创建PCM文件
                mCurrentRecordingStartTime = System.currentTimeMillis();
                mRecordingPath = listener.getOutputFilePath();
                LogUtils.d(TAG, "当前录音文件: " + mRecordingPath);
                mDataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(mRecordingPath)));
                byte[] header = WavHeadUtil.generateWavHeader(0x7FFFFFFFL, sampleRate, 1, 16);
                mDataOutputStream.write(header); // 先写入一个空的文件头
                totalAudioLen = 0;
                mDataOutputStream.write(bytes);
                totalAudioLen += bytes.length;
            } else {
                try {
                    mDataOutputStream.write(bytes);
                    totalAudioLen += bytes.length;
                } catch (IOException e) {
                    LogUtils.e(TAG, "onAudioDataAvailable: " + e.getMessage());
                }
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "onAudioDataAvailable: " + e.getMessage());
        }

    }

    @Override
    public void stopWriteFile() {
        try {
            if (mDataOutputStream != null) {
                long endTime = System.currentTimeMillis();
                mDataOutputStream.flush();
                mDataOutputStream.close();
                mDataOutputStream = null;
                if (mRecordingPath != null) {
                    // 重新打开文件，写入正确的文件头
                    RandomAccessFile raf = new RandomAccessFile(mRecordingPath, "rw");
                    LogUtils.d(TAG, "stopWriteLastFile: totalAudioLen=" + totalAudioLen);
                    WavHeadUtil.updateWavHeader(raf, totalAudioLen);
                    raf.close();
                    listener.onSaveFileFinish(mRecordingPath, mCurrentRecordingStartTime, endTime);
//                    WavHeadUtil.debugWavHeader(new File(mRecordingPath));
                }
            }
        } catch (IOException e) {
            LogUtils.e(TAG, "stopWriteLastFile: " + e.getMessage());
        }
    }


    @Override
    public void release() {
        stopWriteFile();
    }

}
